package com.xhwl.logistics.strategy.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.vehicle.feign.CreateBiVehicleAccessRecordCartypeHourFeignDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.enums.device.DeviceOnlineStatusEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.cent.sdata.Project;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.vo.cent.vehicle.CarVO;
import com.xhwl.logistics.bo.VehicleCarportBO;
import com.xhwl.logistics.bo.VehicleParkingLotSecondBO;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.bo.input.QueryVehicleCarportBO;
import com.xhwl.logistics.bo.manipulate.VehicleSyncBO;
import com.xhwl.logistics.constant.VehicleConstant;
import com.xhwl.logistics.converter.mapstruct.VehicleSyncConverter;
import com.xhwl.logistics.dao.mapper.IVehicleAreaMapper;
import com.xhwl.logistics.dao.mapper.IVehicleCardMapper;
import com.xhwl.logistics.dto.http.*;
import com.xhwl.logistics.dto.http.query.QueryReserveSpaceDaHuaDTO;
import com.xhwl.logistics.dto.query.DeviceControlDTO;
import com.xhwl.logistics.entity.*;
import com.xhwl.logistics.enums.VehicleCarTypeEnum;
import com.xhwl.logistics.service.business.VehicleCommonBusinessService;
import com.xhwl.logistics.service.cent.IBIVehicleService;
import com.xhwl.logistics.service.cent.IDeviceService;
import com.xhwl.logistics.service.cent.IProjectService;
import com.xhwl.logistics.service.impl.*;
import com.xhwl.logistics.service.impl.http.CarDispatchHttpServiceImpl;
import com.xhwl.logistics.service.impl.http.DaHuaHttpServiceImpl;
import com.xhwl.logistics.service.impl.http.HongMenHttpServiceImpl;
import com.xhwl.logistics.strategy.IVehicleParkingLotHandler;
import com.xhwl.logistics.util.AboutDateUtil;
import com.xhwl.logistics.util.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 大华ICC同步车场基本信息的类
 */
@Slf4j
//@Service
public class VehicleParkingLotDaHuaIccHandlerImpl extends AbstractVehicleParkingLotHandlerImpl implements IVehicleParkingLotHandler {

    @Autowired
    private VehicleParkingLotServiceImpl vehicleParkingLotService;

    @Autowired
    private VehicleAreaServiceImpl vehicleAreaService;

    @Autowired
    private VehicleCardServiceImpl vehicleCardService;

    @Autowired
    private IVehicleCardMapper vehicleCardMapper;

    @Autowired
    private IVehicleAreaMapper vehicleAreaMapper;

    @Autowired
    private VehiclePassageServiceImpl vehiclePassageService;

    @Autowired
    private DaHuaHttpServiceImpl daHuaHttpService;

    @Autowired
    private VehicleSyncConverter vehicleSyncConverter;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private VehicleAccessRecordServiceImpl vehicleAccessRecordService;

    @Autowired
    private CarDispatchHttpServiceImpl carDispatchHttpService;

    @Autowired
    private VehicleCarServiceImpl vehicleCarService;

    @Autowired
    private IBIVehicleService ibiVehicleService;

    @Autowired
    private VehicleCommonBusinessService vehicleCommonBusinessService;

    @Autowired
    private HongMenHttpServiceImpl hongMenHttpService;


    private static final Integer barrier = 3;
    //由于Icc无车场概念，又因为要兼容之前的功能，第三方id不能为空，故parkId为空字符串
    private static final String parkId = "";
    private static final Integer enterModel = 1;
    private static final Integer existModel = 1;
    private static final String reservationType = "0";
    private static final Integer deviceYiTiJi = 16;
    private static final String deviceAfterStr = "$14$0$0";

    /**
     * 同步大华车场基础信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleSyncBO
     */
    @Override
    public void sync(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleSyncBO vehicleSyncBO){
        log.info("DaHua sync start");
        log.info("vehicleIntegratedConfigBO{}", vehicleIntegratedConfigBO);
        Integer projectId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId();
        ProjectQuery projectQuery = new ProjectQuery();
        List<Integer> ids = new LinkedList<>();
        ids.add(projectId);
        projectQuery.setIds(ids);
        Project project = projectService.getOne(projectQuery, null);
        //如果项目为空，则结束同步程序
        if(project==null){
            return;
        }
        //判断是否已经存在车场信息，存在就进行更新
        if (vehicleParkingLotService.judgeExistParkingLot(projectId)) {
            log.info("DaHua ParkingLot Sync Already!");
            VehicleParkingLot vehicleParkingLot = vehicleParkingLotService.getOne(new LambdaQueryWrapper<VehicleParkingLot>().eq(VehicleParkingLot::getProjectId, projectId));
            CarSpotStatDaHuaDTO carSpotStatDaHuaDTO = daHuaHttpService.getCarSpotStat(vehicleIntegratedConfigBO);
            vehicleParkingLot.setCarportTotalNumber(carSpotStatDaHuaDTO.getTotalLot());
            //定制化需求
            if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
                if (customParamsObj.getBoolean("doubleFunContrMn")) {
                    JSONObject parkingLot = hongMenHttpService.queryParkingLot(customParamsObj.getString("host"));
                    vehicleParkingLot.setCarportTotalNumber(vehicleParkingLot.getCarportTotalNumber()
                    + parkingLot.getInteger("parking_total"));
                }
            }
            vehicleParkingLot.setParkId(parkId);
            vehicleParkingLotService.updateById(vehicleParkingLot);
        }else{
            //查询大华停车场信息，并保存，大华停车场信息无法查询，由于项目默认只有一个停车场，因此用项目名称造个停车场，大华的查询停车场实际是区域信息
            CarSpotStatDaHuaDTO carSpotStatDaHuaDTO = daHuaHttpService.getCarSpotStat(vehicleIntegratedConfigBO);
            VehicleParkingLot vehicleParkingLot = new VehicleParkingLot();
            vehicleParkingLot.setProjectId(projectId);
            vehicleParkingLot.setCarportTotalNumber(carSpotStatDaHuaDTO.getTotalLot());
            //定制化需求
            if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
                if (customParamsObj.getBoolean("doubleFunContrMn")) {
                    JSONObject parkingLot = hongMenHttpService.queryParkingLot(customParamsObj.getString("host"));
                    vehicleParkingLot.setCarportTotalNumber(vehicleParkingLot.getCarportTotalNumber()
                            + parkingLot.getInteger("parking_total"));
                }
            }
            if (project != null){
                vehicleParkingLot.setParkingLotName(project.getName());
            }
            vehicleParkingLot.setParkId(parkId);
            vehicleParkingLotService.save(vehicleParkingLot);
        }

        VehicleParkingLot vehicleParkingLot = vehicleParkingLotService.getOne(new LambdaQueryWrapper<VehicleParkingLot>().eq(VehicleParkingLot::getProjectId, projectId));

        //同步大华区域（场区）信息
        syncArea(vehicleIntegratedConfigBO, vehicleParkingLot);

        //同步大华车场卡类型
        syncCardType(vehicleIntegratedConfigBO, project, vehicleParkingLot);

        //同步大华的设备
        syncDevices(vehicleIntegratedConfigBO);
        log.info("DaHua sync end");

    }

    /**
     * 同步大华区域信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleParkingLot
     */
    private void syncArea(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleParkingLot vehicleParkingLot){
        //调用大华接口，获取区域信息。
        List<ParkingLotAreaInfoDaHuaDTO> parkingLotAreaInfoDaHuaDTO = daHuaHttpService.getParkingLotAreaInfo(vehicleIntegratedConfigBO);
        //获取数据库中，该停车场中的所有区域信息。
        List<VehicleArea> vehicleAreaList = vehicleAreaMapper.selectList(new LambdaQueryWrapper<VehicleArea>()
                .eq(VehicleArea::getParkingLotId, vehicleParkingLot.getId()));
        //大华的区域信息和中台的区域信息都不为空
        //注：大华的服务类中已经判空了，如果为空直接返回null
        if(parkingLotAreaInfoDaHuaDTO!=null&&!vehicleAreaList.isEmpty()){
            //根据第三方id建立映射集合,建立大华数据的映射
            List<String> thirdIdFromDaHua = parkingLotAreaInfoDaHuaDTO.stream().map(s -> s.getId()).collect(Collectors.toList());
            Map<String, ParkingLotAreaInfoDaHuaDTO> mapForParkingLotAreaInfoDaHuaDTO = parkingLotAreaInfoDaHuaDTO.stream().collect(Collectors.toMap(s -> {
                return s.getId();
            }, Function.identity()));
            //根据第三方id建立映射集合,建立车行中台数据的映射
            List<String> thirdIdFromCentVehicle = vehicleAreaList.stream().map(s -> s.getThirdAreaId()).collect(Collectors.toList());
            Map<String, VehicleArea> mapForVehicleArea = vehicleAreaList.stream().collect(Collectors.toMap(s -> s.getThirdAreaId(), Function.identity()));
            //获取需要新增的区域信息
            List<String> add = ListUtils.subtract(thirdIdFromDaHua, thirdIdFromCentVehicle);
            //将新增的区域信息存入数据库中
            if(!add.isEmpty()){
                List<ParkingLotAreaInfoDaHuaDTO> parkingLotAreaInfoDaHuaDTOS = add.stream().map(mapForParkingLotAreaInfoDaHuaDTO::get).collect(Collectors.toList());
                List<VehicleArea> vehicleAreas = new LinkedList<>();
                for (ParkingLotAreaInfoDaHuaDTO lotAreaInfoDaHuaDTO : parkingLotAreaInfoDaHuaDTOS) {
                    VehicleArea vehicleArea = new VehicleArea();
                    vehicleArea.setAreaName(lotAreaInfoDaHuaDTO.getParkingLot());
                    vehicleArea.setParkingLotId(vehicleParkingLot.getId());
                    vehicleArea.setCarportTotalNumber(lotAreaInfoDaHuaDTO.getTotalLot());
                    //定制化需求
                    if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                        JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                        //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
                        if (customParamsObj.getBoolean("doubleFunContrMn")) {
                            if(StringUtils.equals(customParamsObj.getString("areaCode"), lotAreaInfoDaHuaDTO.getParkingLotCode())){
                                JSONObject parkingLot = hongMenHttpService.queryParkingLot(customParamsObj.getString("host"));
                                vehicleArea.setCarportTotalNumber(vehicleArea.getCarportTotalNumber() + parkingLot.getInteger("parking_total"));
                            }
                        }
                    }
                    vehicleArea.setThirdAreaId(lotAreaInfoDaHuaDTO.getId());
                    vehicleArea.setRemark(lotAreaInfoDaHuaDTO.getParkingLotCode());
                    vehicleAreas.add(vehicleArea);
                }
                vehicleAreaService.saveBatch(vehicleAreas);
            }
            //获取需要删除的区域信息
            List<String> delete = ListUtils.subtract(thirdIdFromCentVehicle, thirdIdFromDaHua);
            //在数据库中删除需要删除的区域信息
            if(!delete.isEmpty()){
                List<VehicleArea> vehicleAreas = delete.stream().map(mapForVehicleArea::get).collect(Collectors.toList());
                List<Integer> ids = vehicleAreas.stream().map(s -> s.getId()).collect(Collectors.toList());
                vehicleAreaService.removeByIds(ids);
            }
            //获取大华和车行中台中重复的部分
            List<String> same = ListUtils.subtract(thirdIdFromCentVehicle, delete);
            //对相同部分的区域信息进行更新
            if(!same.isEmpty()){
                List<VehicleArea> vehicleAreas = new LinkedList<>();
                for (String thirdId : same) {
                    ParkingLotAreaInfoDaHuaDTO parkingLotAreaInfoDaHuaDTO1 = mapForParkingLotAreaInfoDaHuaDTO.get(thirdId);
                    VehicleArea vehicleArea = mapForVehicleArea.get(thirdId);
                    //定制化需求
                    if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                        JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                        //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
                        if (customParamsObj.getBoolean("doubleFunContrMn")) {
                            if(StringUtils.equals(customParamsObj.getString("areaCode"), parkingLotAreaInfoDaHuaDTO1.getParkingLotCode())){
                                JSONObject parkingLot = hongMenHttpService.queryParkingLot(customParamsObj.getString("host"));
                                parkingLotAreaInfoDaHuaDTO1.setTotalLot(parkingLotAreaInfoDaHuaDTO1.getTotalLot() + parkingLot.getInteger("parking_total"));
                            }
                        }
                    }
                    if(StringUtils.equals(vehicleArea.getAreaName(),parkingLotAreaInfoDaHuaDTO1.getParkingLot())&&StringUtils.equals(vehicleArea.getCarportTotalNumber().toString(),parkingLotAreaInfoDaHuaDTO1.getTotalLot().toString())&&StringUtils.equals(vehicleArea.getRemark(),parkingLotAreaInfoDaHuaDTO1.getParkingLotCode())){
                    }else {
                        vehicleArea.setAreaName(parkingLotAreaInfoDaHuaDTO1.getParkingLot());
                        vehicleArea.setCarportTotalNumber(parkingLotAreaInfoDaHuaDTO1.getTotalLot());
                        vehicleArea.setRemark(parkingLotAreaInfoDaHuaDTO1.getParkingLotCode());
                        vehicleAreas.add(vehicleArea);
                    }
                }
                vehicleAreaService.updateBatchById(vehicleAreas);
            }
        }
        //大华的区域信息为空，中台的区域信息不为空
        else if(parkingLotAreaInfoDaHuaDTO==null&&!vehicleAreaList.isEmpty()){
            List<Integer> ids = vehicleAreaList.stream().map(s -> s.getId()).collect(Collectors.toList());
            vehicleAreaService.removeByIds(ids);
        }
        //大华的区域信息不为空，中台的区域信息为空
        else if(parkingLotAreaInfoDaHuaDTO!=null&&vehicleAreaList.isEmpty()){
            LinkedList<VehicleArea> vehicleAreas = new LinkedList<>();
            for (ParkingLotAreaInfoDaHuaDTO lotAreaInfoDaHuaDTO : parkingLotAreaInfoDaHuaDTO) {
                VehicleArea vehicleArea = new VehicleArea();
                vehicleArea.setAreaName(lotAreaInfoDaHuaDTO.getParkingLot());
                vehicleArea.setParkingLotId(vehicleParkingLot.getId());
                vehicleArea.setCarportTotalNumber(lotAreaInfoDaHuaDTO.getTotalLot());
                //定制化需求
                if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                    JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                    //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
                    if (customParamsObj.getBoolean("doubleFunContrMn")) {
                        if(StringUtils.equals(customParamsObj.getString("areaCode"), lotAreaInfoDaHuaDTO.getParkingLotCode())){
                            JSONObject parkingLot = hongMenHttpService.queryParkingLot(customParamsObj.getString("host"));
                            vehicleArea.setCarportTotalNumber(vehicleArea.getCarportTotalNumber() + parkingLot.getInteger("parking_total"));
                        }
                    }
                }
                vehicleArea.setThirdAreaId(lotAreaInfoDaHuaDTO.getId());
                vehicleArea.setRemark(lotAreaInfoDaHuaDTO.getParkingLotCode());
                vehicleAreas.add(vehicleArea);
            }
            vehicleAreaService.saveBatch(vehicleAreas);
        }else{
            //不需要做任何操作
        }

        //获取同步好的区域信息
        List<VehicleArea> vehicleAreas = vehicleAreaMapper.selectList(new LambdaQueryWrapper<VehicleArea>()
                .eq(VehicleArea::getParkingLotId, vehicleParkingLot.getId()));
        //同步大华的通道信息
        for (VehicleArea vehicleArea : vehicleAreas) {
            syncPassage(vehicleIntegratedConfigBO,vehicleParkingLot,vehicleArea.getThirdAreaId(),vehicleArea.getId(), vehicleArea.getRemark());
        }
    }

    /**
     * 同步大华通道信息和设备信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleParkingLot
     */
    private void syncPassage(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleParkingLot vehicleParkingLot, String parkingLotId, Integer areaId, String areaCode){
        List<VehiclePassage> vehiclePassageThirdList = new LinkedList<>();

        //获取大华下该区域的所有通道信息
        List<PassageAndDeviceDaHuaDTO> passageAndDeviceDaHuaDTOS = daHuaHttpService.getPassageAndDeviceList(vehicleIntegratedConfigBO, parkingLotId);
        //获取车行中台下该区域的所有通道信息
        List<VehiclePassage> vehiclePassageList = vehiclePassageService.list(new LambdaQueryWrapper<VehiclePassage>().eq(VehiclePassage::getAreaId, areaId).eq(VehiclePassage::getProjectId,vehicleParkingLot.getProjectId()));
        if(passageAndDeviceDaHuaDTOS != null) {
            for (PassageAndDeviceDaHuaDTO passageAndDeviceDaHuaDTO : passageAndDeviceDaHuaDTOS) {
                VehiclePassage vehiclePassage = new VehiclePassage();
                vehiclePassage.setPassageName(passageAndDeviceDaHuaDTO.getTideName());
                vehiclePassage.setType(convertDaHuaPassageType(Integer.parseInt(passageAndDeviceDaHuaDTO.getCarDirect())));
                vehiclePassage.setProjectId(vehicleParkingLot.getProjectId());
                vehiclePassage.setParkingLotId(vehicleParkingLot.getId());
                vehiclePassage.setAreaId(areaId);
                vehiclePassage.setThirdPassageId(passageAndDeviceDaHuaDTO.getChannelId());
                //在备注中存储设备与通道的绑定关系，便于之后的统一
                vehiclePassage.setRemark(this.passageIdToDeviceId(passageAndDeviceDaHuaDTO));
                vehiclePassageThirdList.add(vehiclePassage);
            }
        }
        //定制化需求
        if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null){
            JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
            //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
            if(customParamsObj.getBoolean("doubleFunContrMn")){
                //查看此次同步的区域是否是第二个厂商需要的
                if(StringUtils.equals(areaCode, customParamsObj.getString("areaCode"))){
                    JSONArray passageArr = hongMenHttpService.queryPassageInfo(customParamsObj.getString("host"));
                    for (Object object : passageArr) {
                        JSONObject passageObj = JSONObject.parseObject(object.toString());
                        VehiclePassage vehiclePassage = new VehiclePassage();
                        vehiclePassage.setPassageName(passageObj.getString("channel_name"));
                        vehiclePassage.setType(this.convertHongMenPassageType(passageObj.getInteger("direction")));
                        vehiclePassage.setProjectId(vehicleParkingLot.getProjectId());
                        vehiclePassage.setParkingLotId(vehicleParkingLot.getId());
                        vehiclePassage.setAreaId(areaId);
                        vehiclePassage.setThirdPassageId(passageObj.getString("channel_id"));
                        vehiclePassage.setRemark(this.syncHongMenDevicePassage(vehicleIntegratedConfigBO, passageObj.getString("channel_id"),
                                customParamsObj.getString("host")));
                        vehiclePassageThirdList.add(vehiclePassage);
                    }
                }
            }
        }
        vehicleCommonBusinessService.syncPassage(vehiclePassageList, vehiclePassageThirdList);
    }

    /**
     * 转换大华的通道出入类型
     * @param carDirect
     * == 8 驶入 == 0 入
     * == 9 驶出 == 1 出
     * @return
     */
    private Integer convertDaHuaPassageType(Integer carDirect){
        switch (carDirect){
            case 8:
                return 0;
            case 9:
                return 1;
            default:
                return null;
        }
    }

    /**
     * 转换红门的通道出入类型
     */
    private Integer convertHongMenPassageType(Integer carDirect){
        switch (carDirect){
            case 0:
                return 0;
            case 1:
                return 1;
            default:
                return null;
        }
    }

    /**
     * 同步大华车场卡类型
     * @param vehicleIntegratedConfigBO
     * @param project
     * @param vehicleParkingLot
     */
    private void syncCardType(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, Project project, VehicleParkingLot vehicleParkingLot){
        //查询大华停车场的用户类型信息，并转换为卡类型保存
        List<CardTypeDaHuaDTO> cardTypeDaHuaDTOS = daHuaHttpService.getCardType(vehicleIntegratedConfigBO);
        //查询车行中台的卡类型信息
        List<VehicleCard> vehicleCardList = vehicleCardService.list(new LambdaQueryWrapper<VehicleCard>().eq(VehicleCard::getProjectId, project.getId()).eq(VehicleCard::getParkingLotId, vehicleParkingLot.getId()));
        //大华的用户类型为空和车行的用户类型都不为空
        if(cardTypeDaHuaDTOS!=null&&!vehicleCardList.isEmpty()){
            //根据第三方id建立映射集合，建立大华的集合映射
            List<String> thirdForDaHua = cardTypeDaHuaDTOS.stream().map(s -> s.getId()).collect(Collectors.toList());
            Map<String, CardTypeDaHuaDTO> mapForCardTypeDaHuaDTO = cardTypeDaHuaDTOS.stream().collect(Collectors.toMap(s -> s.getId(), Function.identity()));
            //根据第三方id建立映射集合，建立车行中台的集合映射
            List<String> thirdForCentVehicle = vehicleCardList.stream().map(s -> s.getThirdRuleId()).collect(Collectors.toList());
            Map<String, VehicleCard> mapForVehicleCard = vehicleCardList.stream().collect(Collectors.toMap(s -> s.getThirdRuleId(), Function.identity()));
            //获取需要新增的卡类型
            List<String> add = ListUtils.subtract(thirdForDaHua, thirdForCentVehicle);
            //将需要新增的卡类型保存进数据库中
            if(!add.isEmpty()){
                List<CardTypeDaHuaDTO> cardTypeDaHuaDTOList = add.stream().map(mapForCardTypeDaHuaDTO::get).collect(Collectors.toList());
                List<VehicleCard> vehicleCards = new LinkedList<>();
                for (CardTypeDaHuaDTO cardTypeDaHuaDTO : cardTypeDaHuaDTOList) {
                    VehicleCard vehicleCard = new VehicleCard();
                    vehicleCard.setProjectId(project.getId());
                    vehicleCard.setProjectName(project.getName());
                    vehicleCard.setParkingLotId(vehicleParkingLot.getId());
                    vehicleCard.setParkingLotName(vehicleParkingLot.getParkingLotName());
                    vehicleCard.setName(cardTypeDaHuaDTO.getTypeName());
                    vehicleCard.setCardType(convertDaHuaCardType(cardTypeDaHuaDTO.getOwnerType()));
                    vehicleCard.setThirdRuleId(cardTypeDaHuaDTO.getId());
                    vehicleCards.add(vehicleCard);
                }
                vehicleCardService.saveBatch(vehicleCards);
            }
            //获取需要删除的卡类型
            List<String> delete = ListUtils.subtract(thirdForCentVehicle, thirdForDaHua);
            //将需要删除的卡类型从数据库中删除
            if(!delete.isEmpty()){
                List<VehicleCard> vehicleCards = delete.stream().map(mapForVehicleCard::get).collect(Collectors.toList());
                List<Integer> ids = vehicleCards.stream().map(s -> s.getId()).collect(Collectors.toList());
                vehicleCardService.removeByIds(ids);
            }
            //获取需要修改的卡类型
            List<String> same = ListUtils.subtract(thirdForCentVehicle, delete);
            //对需要修改的卡类型，在数据库中做相应的修改
            if(!same.isEmpty()){
                List<VehicleCard> vehicleCards = new LinkedList<>();
                for (String thirdId : same) {
                    CardTypeDaHuaDTO cardTypeDaHuaDTO = mapForCardTypeDaHuaDTO.get(thirdId);
                    VehicleCard vehicleCard = mapForVehicleCard.get(thirdId);
                    if(StringUtils.equals(cardTypeDaHuaDTO.getTypeName(),vehicleCard.getName())&&StringUtils.equals(convertDaHuaCardType(cardTypeDaHuaDTO.getOwnerType()).toString(),vehicleCard.getCardType().toString())){

                    }else{
                        vehicleCard.setName(cardTypeDaHuaDTO.getTypeName());
                        vehicleCard.setCardType(convertDaHuaCardType(cardTypeDaHuaDTO.getOwnerType()));
                        vehicleCards.add(vehicleCard);
                    }
                }
                vehicleCardService.updateBatchById(vehicleCards);
            }
        }
        //大华卡类型为空，车行中台的卡类型不为空
        else if(cardTypeDaHuaDTOS==null&&!vehicleCardList.isEmpty()){
            List<Integer> ids = vehicleCardList.stream().map(s -> s.getId()).collect(Collectors.toList());
            vehicleCardService.removeByIds(ids);
        }
        //大华的卡类型不为空，车行中台的卡类型为空
        else if (cardTypeDaHuaDTOS!=null&&vehicleCardList.isEmpty()){
            List<VehicleCard> vehicleCards = new LinkedList<>();
            for (CardTypeDaHuaDTO cardTypeDaHuaDTO : cardTypeDaHuaDTOS) {
                VehicleCard vehicleCard = new VehicleCard();
                vehicleCard.setProjectId(project.getId());
                vehicleCard.setProjectName(project.getName());
                vehicleCard.setParkingLotId(vehicleParkingLot.getId());
                vehicleCard.setParkingLotName(vehicleParkingLot.getParkingLotName());
                vehicleCard.setName(cardTypeDaHuaDTO.getTypeName());
                vehicleCard.setCardType(convertDaHuaCardType(cardTypeDaHuaDTO.getOwnerType()));
                vehicleCard.setThirdRuleId(cardTypeDaHuaDTO.getId());
                vehicleCards.add(vehicleCard);
            }
            vehicleCardService.saveBatch(vehicleCards);
        }
    }

    /**
     * 转换大华的卡类型为中台的卡类型枚举
     * @param ownerType
     * == 3 长期用户 == 0 免费卡
     * == 2 月卡用户 == 1 月卡
     * == 1 储值用户 == 2 储值卡
     * == 0 临时用户 == 3 临时卡
     * @return cardType
     */
    private Integer convertDaHuaCardType(Integer ownerType){
        switch (ownerType){
            case 0:
                return 3;
            case 1:
                return 2;
            case 2:
                return 1;
            case 3:
                return 0;
            default:
                return null;
        }
    }

    /**
     * 同步车场设备
     * @param vehicleIntegratedConfigBO
     */
    private void syncDevices(VehicleIntegratedConfigBO vehicleIntegratedConfigBO){
        List<DeviceInfoDaHuaIccDTO> daHuaDeviceList = daHuaHttpService.getDaHuaDevice(vehicleIntegratedConfigBO);
        List<DeviceDTO> deviceDTOS = new LinkedList<>();
        if(daHuaDeviceList != null){
            for (DeviceInfoDaHuaIccDTO deviceInfoDaHuaIccDTO : daHuaDeviceList) {
                DeviceDTO deviceDTO = new DeviceDTO();
                deviceDTO.setProjectId(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId());
                deviceDTO.setProductId(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId());
                deviceDTO.setThirdDeviceId(deviceInfoDaHuaIccDTO.getChannelCode());
                deviceDTO.setName(deviceInfoDaHuaIccDTO.getChannelName());
                //设备告警使用的是iotDeviceId字段
                deviceDTO.setIotDeviceId(deviceInfoDaHuaIccDTO.getDeviceIp());
                deviceDTO.setOnlineStatus(Integer.parseInt(deviceInfoDaHuaIccDTO.getIsOnline()));
                deviceDTO.setCategoryId(CategoryEnum.YARD_GATE.getId());
                deviceDTO.setDeviceTypeId(barrier);
                deviceDTOS.add(deviceDTO);
            }
        }
        deviceService.asyncUpdateDevice(deviceDTOS);

        //定制化需求
        if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
            JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
            //doubleFunContrMn为true表示开启蒙牛双厂商功能，定制化需求
            if (customParamsObj.getBoolean("doubleFunContrMn")) {
                JSONArray channelArr = hongMenHttpService.queryDeviceByPassage(customParamsObj.getString("host"), null);
                List<DeviceDTO> deviceDTOS1 = new LinkedList<>();
                for (Object object : channelArr) {
                    JSONObject channelObj = JSONObject.parseObject(object.toString());
                    JSONArray deviceArr = JSONObject.parseArray(channelObj.getString("equipments"));
                    for (Object object2 : deviceArr) {
                        JSONObject deviceObj = JSONObject.parseObject(object2.toString());
                        DeviceDTO deviceDTO = new DeviceDTO();
                        deviceDTO.setProjectId(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId());
                        deviceDTO.setProductId(customParamsObj.getInteger("productId"));
                        deviceDTO.setCategoryId(CategoryEnum.YARD_GATE.getId());
                        deviceDTO.setDeviceTypeId(barrier);
                        deviceDTO.setName(deviceObj.getString("name"));
                        deviceDTO.setThirdDeviceId(deviceObj.getString("id"));
                        deviceDTO.setOnlineStatus(this.convertHongMenDeviceStatus(deviceObj.getString("state")));
                        deviceDTOS1.add(deviceDTO);
                    }
                }
                deviceService.asyncUpdateDevice(deviceDTOS1);
            }
        }
    }

    /**
     * 同步红门车行的设备信息，定制化需求
     */
    private String syncHongMenDevicePassage(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, String channelId, String path){
        JSONArray channelArr = hongMenHttpService.queryDeviceByPassage(path, channelId);
        StringBuilder deviceIds = new StringBuilder();
        for (Object object : channelArr) {
            JSONObject channelObj = JSONObject.parseObject(object.toString());
            JSONArray deviceArr = JSONObject.parseArray(channelObj.getString("equipments"));
            for (Object object2 : deviceArr) {
                JSONObject deviceObj = JSONObject.parseObject(object2.toString());
                //将设备id组合起来，便于通道与设备之间的绑定
                deviceIds.append(deviceObj.getString("id")).append(",");
            }
        }
        return deviceIds.toString();
    }

    /**
     * 转换红门车行的设备状态
     */
    private Integer convertHongMenDeviceStatus(String deviceStatus){
        switch (deviceStatus){
            case "CONNECTED":
                return DeviceOnlineStatusEnum.ONLINE.getId();
            default:
                return DeviceOnlineStatusEnum.OFFLINE.getId();
        }
    }

    @Override
    public VehicleCarportBO queryCarport(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, QueryVehicleCarportBO queryVehicleCarportBO) {
        return daHuaHttpService.getDaHuaFreeCarSpot(vehicleIntegratedConfigBO);
    }

    @Override
    public void openDevice(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, DeviceControlDTO deviceControlDTO) {
        //判断前端传的是设备id还是通道id，controlDevice不存在或为false表示为通道id，为true表示为设备id
        if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getControlDevice() == null ||
                !vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getControlDevice()){
            VehiclePassage vehiclePassage = vehiclePassageService.getById(deviceControlDTO.getId());
            if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null){
                JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                if(customParamsObj.getBoolean("doubleFunContrMn")){
                    String[] deviceRemarks = vehiclePassage.getRemark().split(",");
                    DevicePageQuery devicePageQuery = new DevicePageQuery();
                    devicePageQuery.setProjectId(deviceControlDTO.getProjectId());
                    devicePageQuery.setThirdDeviceIdList(Arrays.stream(deviceRemarks).collect(Collectors.toList()));
                    List<DeviceDTO> deviceDTOList = deviceService.listDevice(null, devicePageQuery);
                    if(deviceDTOList.isEmpty()){
                        throw new BusinessException("该通道不存在设备，无法控制");
                    }
                    if(!vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId().equals(deviceDTOList.get(0).getProductId())){
                        log.info("使用通道id控制红门道闸");
                        hongMenHttpService.openChannel(customParamsObj.getString("host"), vehiclePassage.getThirdPassageId());
                        return;
                    }
                }
            }
            log.info("使用通道id控制大华ICC道闸");
            daHuaHttpService.controlDevice(vehicleIntegratedConfigBO, vehiclePassage.getThirdPassageId());
        }else{
            DevicePageQuery devicePageQuery = new DevicePageQuery();
            devicePageQuery.setId(deviceControlDTO.getId());
            List<DeviceDTO> deviceDTOList = deviceService.listDevice(null, devicePageQuery);
            if(deviceDTOList.isEmpty()){
                throw new BusinessException("未找到该设备");
            }
            if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null) {
                JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
                if (customParamsObj.getBoolean("doubleFunContrMn")) {
                    if(!vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProductId().equals(deviceDTOList.get(0).getProductId())){
                        List<VehiclePassage> vehiclePassages = vehiclePassageService.list();
                        VehiclePassage vehiclePassage1 = vehiclePassages.stream().filter(vehiclePassage -> {
                            String[] deviceRemarks = vehiclePassage.getRemark().split(",");
                            List<String> deviceRemarkList = Arrays.stream(deviceRemarks).collect(Collectors.toList());
                            if (deviceRemarkList.contains(deviceDTOList.get(0).getThirdDeviceId())) {
                                return true;
                            } else {
                                return false;
                            }
                        }).findAny().orElse(null);
                        if(vehiclePassage1 != null){
                            log.info("使用设备id控制红门道闸");
                            hongMenHttpService.openChannel(customParamsObj.getString("host"), vehiclePassage1.getThirdPassageId());
                            return;
                        }else{
                            throw new BusinessException("通过该设备未找到相应的通道");
                        }
                    }
                }
            }
            List<VehiclePassage> vehiclePassageList = vehiclePassageService.list(new LambdaQueryWrapper<VehiclePassage>()
                    .eq(VehiclePassage::getProjectId, vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId())
                    .eq(VehiclePassage::getRemark, deviceDTOList.get(0).getThirdDeviceId()));
            if(vehiclePassageList.isEmpty()){
                throw new BusinessException("未找到与这个设备绑定的通道信息");
            }
            log.info("使用通道id控制大华ICC道闸");
            daHuaHttpService.controlDevice(vehicleIntegratedConfigBO,vehiclePassageList.get(0).getThirdPassageId());
        }

    }

    @Override
    protected List<VehicleParkingLotSecondBO> queryParkingLots(Integer projectId, String parkingLotName){
        List<VehicleParkingLotSecondBO> parkingLotSecondBOS = new ArrayList<>();
        return parkingLotSecondBOS;
    }

    @Override
    protected VehicleParkingLotSecondBO queryParkingLot(Integer projectId){
        VehicleParkingLotSecondBO vehicleParkingLotSecondBO = new VehicleParkingLotSecondBO();
        return vehicleParkingLotSecondBO;
    }

    @Override
    protected VehicleCarportBO getVehicleCarportBOFromHttp(VehicleIntegratedConfigBO vehicleIntegratedConfigBO){
        VehicleCarportBO vehicleCarportBO = new VehicleCarportBO();
        return vehicleCarportBO;
    }

    @Override
    protected Integer statisticsEnterCount(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected Integer statisticsGoOutCount(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected void pushDwsAccessRecordForHourDataToCentBi(Integer projectId, String parkingLotName,
                                                                   Integer totalForCount, Integer enterForCount, Integer goOutForCount,
                                                                   Date processDate, Date ingestionDate){

    }

    @Override
    protected Integer statisticsTotalPaySum(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected void pushDwsPayRecordForHourDataToCentBi(Integer projectId, String parkingLotName,
                                                                Integer totalPay, Integer webChatPay, Integer aliPay, Integer onlinePay, Integer other,
                                                                Date processDate, Date ingestionDate){

    }

    /**
     * 通过一些条件查询进记录
     */
    private Wrapper<VehicleAccessRecord> conditionForAccessRecordInFromArea(Integer projectId, String remark, Date startTime, Date endTime){
        return new LambdaQueryWrapper<VehicleAccessRecord>()
                .eq(VehicleAccessRecord::getProjectId, projectId)
                .eq(Objects.nonNull(remark), VehicleAccessRecord::getParkId, remark)
                .ge(VehicleAccessRecord::getEnterTime, startTime)
                .lt(VehicleAccessRecord::getEnterTime, endTime);
    }

    /**
     * 通过一些条件查询进记录
     */
    private Wrapper<VehicleAccessRecord> conditionForAccessRecordOutFromArea(Integer projectId, String remark, Date startTime, Date endTime, Date enterTime){
        return new LambdaQueryWrapper<VehicleAccessRecord>()
                .eq(VehicleAccessRecord::getProjectId, projectId)
                .eq(Objects.nonNull(remark), VehicleAccessRecord::getParkId, remark)
                .ge(VehicleAccessRecord::getEnterTime, enterTime)
                .ge(VehicleAccessRecord::getExitTime, startTime)
                .lt(VehicleAccessRecord::getExitTime, endTime);
    }

    /**
     * 通过项目id查询车辆
     */
    private Wrapper<VehicleCar> conditionForCarFromProjectId(Integer projectId){
        return new LambdaQueryWrapper<VehicleCar>()
                .eq(VehicleCar::getProjectId, projectId);
    }

    @Override
    public void statisticsToBi(VehicleIntegratedConfigBO vehicleIntegratedConfigBO) {

        if(StringUtils.isEmpty(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemark())){
            return;
        }

        Date processDate = new Date();
        Date enterTime = AboutDateUtil.theSameDayOfDate(processDate);
        Date endTime = AboutDateUtil.theSameDayHourOfDate(processDate, VehicleConstant.vehicleTimeZone);
        Date ingestionDate = AboutDateUtil.dateMinusHour(endTime, 1);

        log.info("dahua statistics access record carType start!,project id: {}", vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId());

        Integer projectId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId();

        VehicleParkingLotSecondBO vehicleParkingLotSecondBO = vehicleParkingLotService.queryParkingLot(projectId, null);
        String parkingLotName = vehicleParkingLotSecondBO.getParkingLotName();
        String parkId = vehicleParkingLotSecondBO.getParkId();

        List<VehicleAccessRecord> vehicleAccessRecordListInA = vehicleAccessRecordService.list(conditionForAccessRecordInFromArea(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId(),
                vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemark(), ingestionDate, endTime));
        List<VehicleAccessRecord> vehicleAccessRecordListInB = vehicleAccessRecordService.list(conditionForAccessRecordInFromArea(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId(),
                vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemarkUnion(), ingestionDate, endTime));
        List<VehicleAccessRecord> vehicleAccessRecordListOutA = vehicleAccessRecordService.list(conditionForAccessRecordOutFromArea(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId(),
                vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemark(), ingestionDate, endTime, enterTime));
        List<VehicleAccessRecord> vehicleAccessRecordListOutB = vehicleAccessRecordService.list(conditionForAccessRecordOutFromArea(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId(),
                vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemarkUnion(), ingestionDate, endTime, enterTime));

        List<String> plateInB = vehicleAccessRecordListInB.stream().map(VehicleAccessRecord::getPlateNumber).collect(Collectors.toList());
        List<String> plateOutB = vehicleAccessRecordListOutB.stream().map(VehicleAccessRecord::getPlateNumber).collect(Collectors.toList());
        plateInB.addAll(plateOutB);
        //去重
        List<String> plateNumbersFromB = MathUtil.noRepetFromString(plateInB);
        List<CarDispatchMapDTO> carTypeByCarNum = carDispatchHttpService.getCarTypeByCarNum(vehicleIntegratedConfigBO, plateNumbersFromB);

        List<VehicleCar> vehicleCarList = vehicleCarService.list(conditionForCarFromProjectId(vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId()));

        CreateBiVehicleAccessRecordCartypeHourFeignDTO createBiVehicleAccessRecordCartypeHourFeignDTO = this.toCreateBiVehicleAccessRecordCartypeHourFeignDTO(
                vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId(), parkingLotName,
                vehicleAccessRecordListInA, vehicleAccessRecordListInB, vehicleAccessRecordListOutA,
                vehicleAccessRecordListOutB, carTypeByCarNum, vehicleCarList, processDate, ingestionDate
        );
        ibiVehicleService.addDwsAccessRecordCartypeForHour(createBiVehicleAccessRecordCartypeHourFeignDTO);

        log.info("dahua statistics access record carType end!,project id: {}", vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId());
    }

    /**
     * 将出行记录转换为按车辆类型统计出行记录
     */
    private CreateBiVehicleAccessRecordCartypeHourFeignDTO toCreateBiVehicleAccessRecordCartypeHourFeignDTO(
            Integer projectId, String parkingName, List<VehicleAccessRecord> vehicleAccessRecordListInA,
            List<VehicleAccessRecord> vehicleAccessRecordListInB,List<VehicleAccessRecord> vehicleAccessRecordListOutA,
            List<VehicleAccessRecord> vehicleAccessRecordListOutB,List<CarDispatchMapDTO> carTypeByCarNum,
            List<VehicleCar> vehicleCarList, Date processDate, Date ingestionDate
    ){
        CreateBiVehicleAccessRecordCartypeHourFeignDTO cartypeHourFeignDTO = new CreateBiVehicleAccessRecordCartypeHourFeignDTO();
        cartypeHourFeignDTO.setProjectId(projectId);
        cartypeHourFeignDTO.setParkingName(parkingName);
        cartypeHourFeignDTO.setProcessTime(processDate);
        cartypeHourFeignDTO.setIngestionTime(ingestionDate);

        //内部员工进
        vehicleAccessRecordListInA.forEach(vehicleAccessRecord -> {
            String carType = carTypeByCarNumFromCent(vehicleAccessRecord.getPlateNumber(), vehicleCarList);
            switch (carType){
                case "汽车":
                    cartypeHourFeignDTO.setMobileCarTotal(cartypeHourFeignDTO.getMobileCarTotal() + 1);
                    cartypeHourFeignDTO.setMobileCarIn(cartypeHourFeignDTO.getMobileCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "中大型汽车":
                    cartypeHourFeignDTO.setBigMobileCarTotal(cartypeHourFeignDTO.getBigMobileCarTotal() + 1);
                    cartypeHourFeignDTO.setBigMobileCarIn(cartypeHourFeignDTO.getBigMobileCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "警车":
                    cartypeHourFeignDTO.setPoliceCarTotal(cartypeHourFeignDTO.getPoliceCarTotal() + 1);
                    cartypeHourFeignDTO.setPoliceCarIn(cartypeHourFeignDTO.getPoliceCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "新能源车":
                    cartypeHourFeignDTO.setEnergyCarTotal(cartypeHourFeignDTO.getEnergyCarTotal() + 1);
                    cartypeHourFeignDTO.setEnergyCarIn(cartypeHourFeignDTO.getEnergyCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "中大型客车":
                    cartypeHourFeignDTO.setGuestCarTotal(cartypeHourFeignDTO.getGuestCarTotal() + 1);
                    cartypeHourFeignDTO.setGuestCarIn(cartypeHourFeignDTO.getGuestCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "货车":
                    cartypeHourFeignDTO.setGoodsCarTotal(cartypeHourFeignDTO.getGoodsCarTotal() + 1);
                    cartypeHourFeignDTO.setGoodsCarIn(cartypeHourFeignDTO.getGoodsCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "摩托车":
                    cartypeHourFeignDTO.setMotorbikeTotal(cartypeHourFeignDTO.getMotorbikeTotal() + 1);
                    cartypeHourFeignDTO.setMotorbikeIn(cartypeHourFeignDTO.getMotorbikeIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "非货车":
                    cartypeHourFeignDTO.setOtherCarTotal(cartypeHourFeignDTO.getOtherCarTotal() + 1);
                    cartypeHourFeignDTO.setOtherCarIn(cartypeHourFeignDTO.getOtherCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                default:
                    break;
            }
        });

        //货车区进
        vehicleAccessRecordListInB.forEach(vehicleAccessRecord -> {
            String carType = carTypeByCarNumFromThird(vehicleAccessRecord.getPlateNumber(), carTypeByCarNum);
            switch (carType){
                case "成品车":
                    cartypeHourFeignDTO.setFinishedCarTotal(cartypeHourFeignDTO.getFinishedCarTotal() + 1);
                    cartypeHourFeignDTO.setFinishedCarIn(cartypeHourFeignDTO.getFinishedCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "原辅料车":
                    cartypeHourFeignDTO.setPurchaseCarTotal(cartypeHourFeignDTO.getPurchaseCarTotal() + 1);
                    cartypeHourFeignDTO.setPurchaseCarIn(cartypeHourFeignDTO.getPurchaseCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "奶车":
                    cartypeHourFeignDTO.setMilkCarTotal(cartypeHourFeignDTO.getMilkCarTotal() + 1);
                    cartypeHourFeignDTO.setMilkCarIn(cartypeHourFeignDTO.getMilkCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "稀奶油车":
                    cartypeHourFeignDTO.setXnyCarTotal(cartypeHourFeignDTO.getXnyCarTotal() + 1);
                    cartypeHourFeignDTO.setXnyCarIn(cartypeHourFeignDTO.getXnyCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "原奶外送车":
                    cartypeHourFeignDTO.setMilkOutCarTotal(cartypeHourFeignDTO.getMilkOutCarTotal() + 1);
                    cartypeHourFeignDTO.setMilkOutCarIn(cartypeHourFeignDTO.getMilkOutCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "火车倒运车":
                    cartypeHourFeignDTO.setTrainCarTotal(cartypeHourFeignDTO.getTrainCarTotal() + 1);
                    cartypeHourFeignDTO.setTrainCarIn(cartypeHourFeignDTO.getTrainCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "槽车":
                    cartypeHourFeignDTO.setSlotCarTotal(cartypeHourFeignDTO.getSlotCarTotal() + 1);
                    cartypeHourFeignDTO.setSlotCarIn(cartypeHourFeignDTO.getSlotCarIn()+ 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "非货车":
                    cartypeHourFeignDTO.setOtherCarTotal(cartypeHourFeignDTO.getOtherCarTotal() + 1);
                    cartypeHourFeignDTO.setOtherCarIn(cartypeHourFeignDTO.getOtherCarIn() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                default:
                    break;
            }
        });

        //内部员工出
        vehicleAccessRecordListOutA.forEach(vehicleAccessRecord -> {
            String carType = carTypeByCarNumFromCent(vehicleAccessRecord.getPlateNumber(), vehicleCarList);
            switch (carType){
                case "汽车":
                    cartypeHourFeignDTO.setMobileCarTotal(cartypeHourFeignDTO.getMobileCarTotal() + 1);
                    cartypeHourFeignDTO.setMobileCarOut(cartypeHourFeignDTO.getMobileCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "中大型汽车":
                    cartypeHourFeignDTO.setBigMobileCarTotal(cartypeHourFeignDTO.getBigMobileCarTotal() + 1);
                    cartypeHourFeignDTO.setBigMobileCarOut(cartypeHourFeignDTO.getBigMobileCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "警车":
                    cartypeHourFeignDTO.setPoliceCarTotal(cartypeHourFeignDTO.getPoliceCarTotal() + 1);
                    cartypeHourFeignDTO.setPoliceCarOut(cartypeHourFeignDTO.getPoliceCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "新能源车":
                    cartypeHourFeignDTO.setEnergyCarTotal(cartypeHourFeignDTO.getEnergyCarTotal() + 1);
                    cartypeHourFeignDTO.setEnergyCarOut(cartypeHourFeignDTO.getEnergyCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "中大型客车":
                    cartypeHourFeignDTO.setGuestCarTotal(cartypeHourFeignDTO.getGuestCarTotal() + 1);
                    cartypeHourFeignDTO.setGuestCarOut(cartypeHourFeignDTO.getGuestCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "货车":
                    cartypeHourFeignDTO.setGoodsCarTotal(cartypeHourFeignDTO.getGoodsCarTotal() + 1);
                    cartypeHourFeignDTO.setGoodsCarOut(cartypeHourFeignDTO.getGoodsCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "摩托车":
                    cartypeHourFeignDTO.setMotorbikeTotal(cartypeHourFeignDTO.getMotorbikeTotal() + 1);
                    cartypeHourFeignDTO.setMotorbikeOut(cartypeHourFeignDTO.getMotorbikeOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "非货车":
                    cartypeHourFeignDTO.setOtherCarTotal(cartypeHourFeignDTO.getOtherCarTotal() + 1);
                    cartypeHourFeignDTO.setOtherCarOut(cartypeHourFeignDTO.getOtherCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                default:
                    break;
            }
        });

        //货车区出
        vehicleAccessRecordListOutB.forEach(vehicleAccessRecord -> {
            String carType = carTypeByCarNumFromThird(vehicleAccessRecord.getPlateNumber(), carTypeByCarNum);
            switch (carType){
                case "成品车":
                    cartypeHourFeignDTO.setFinishedCarTotal(cartypeHourFeignDTO.getFinishedCarTotal() + 1);
                    cartypeHourFeignDTO.setFinishedCarOut(cartypeHourFeignDTO.getFinishedCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "原辅料车":
                    cartypeHourFeignDTO.setPurchaseCarTotal(cartypeHourFeignDTO.getPurchaseCarTotal() + 1);
                    cartypeHourFeignDTO.setPurchaseCarOut(cartypeHourFeignDTO.getPurchaseCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "奶车":
                    cartypeHourFeignDTO.setMilkCarTotal(cartypeHourFeignDTO.getMilkCarTotal() + 1);
                    cartypeHourFeignDTO.setMilkCarOut(cartypeHourFeignDTO.getMilkCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "稀奶油车":
                    cartypeHourFeignDTO.setXnyCarTotal(cartypeHourFeignDTO.getXnyCarTotal() + 1);
                    cartypeHourFeignDTO.setXnyCarOut(cartypeHourFeignDTO.getXnyCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "原奶外送车":
                    cartypeHourFeignDTO.setMilkOutCarTotal(cartypeHourFeignDTO.getMilkOutCarTotal() + 1);
                    cartypeHourFeignDTO.setMilkOutCarOut(cartypeHourFeignDTO.getMilkOutCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "火车倒运车":
                    cartypeHourFeignDTO.setTrainCarTotal(cartypeHourFeignDTO.getTrainCarTotal() + 1);
                    cartypeHourFeignDTO.setTrainCarOut(cartypeHourFeignDTO.getTrainCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "槽车":
                    cartypeHourFeignDTO.setSlotCarTotal(cartypeHourFeignDTO.getSlotCarTotal() + 1);
                    cartypeHourFeignDTO.setSlotCarOut(cartypeHourFeignDTO.getSlotCarOut() + 1);
                    cartypeHourFeignDTO.setIn(cartypeHourFeignDTO.getIn() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                case "非货车":
                    cartypeHourFeignDTO.setOtherCarTotal(cartypeHourFeignDTO.getOtherCarTotal() + 1);
                    cartypeHourFeignDTO.setOtherCarOut(cartypeHourFeignDTO.getOtherCarOut() + 1);
                    cartypeHourFeignDTO.setOut(cartypeHourFeignDTO.getOut() + 1);
                    cartypeHourFeignDTO.setTotal(cartypeHourFeignDTO.getTotal() + 1);
                    break;
                default:
                    break;
            }
        });

        return cartypeHourFeignDTO;
    }

    /**
     * 通过车牌号判断车辆类型，从车辆调度中
     */
    private String carTypeByCarNumFromThird(String plateNumber, List<CarDispatchMapDTO> carTypeByCarNum){
        CarDispatchMapDTO carDispatchMapDTO1 = carTypeByCarNum.stream().filter(carDispatchMapDTO -> {
            if (StringUtils.equals(carDispatchMapDTO.getKey(), plateNumber)) {
                return true;
            } else {
                return false;
            }
        }).findAny().orElse(null);
        if(carDispatchMapDTO1!=null){
            return carDispatchMapDTO1.getValue();
        }else{
            return "非货车";
        }
    }

    /**
     * 通过车牌号判断车辆类型，在中台中
     */
    private String carTypeByCarNumFromCent(String plateNumber, List<VehicleCar> vehicleCarList){
        VehicleCar vehicleCar1 = vehicleCarList.stream().filter(vehicleCar -> {
            if (StringUtils.equals(vehicleCar.getPlateNumber(), plateNumber)) {
                return true;
            } else {
                return false;
            }
        }).findAny().orElse(null);
        if(vehicleCar1 != null){
            return VehicleCarTypeEnum.toVehicleCarTypeEnum(vehicleCar1.getCarType()).getDescription();
        }else{
            return "非货车";
        }
    }

    /**
     * 访客车预约新增
     */
    @Override
    public String reserverSpace(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, CarVO carVO) {
        QueryReserveSpaceDaHuaDTO queryReserveSpaceDaHuaDTO = carVOtoQueryReserveSpaceDaHuaDTO(vehicleIntegratedConfigBO, carVO);
        String orederNo = "";
        try{
            orederNo = daHuaHttpService.reserveCar(vehicleIntegratedConfigBO, queryReserveSpaceDaHuaDTO);
        }catch (Exception e){
            throw new DataException("预约失败");
        }

        //查看是否开启了蒙牛红门双厂商的定制化需求
        if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null){
            JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
            if(customParamsObj.getBoolean("doubleFunContrMn")){
                try {
                    hongMenHttpService.addVisitorCar(customParamsObj.getString("host"), carVO);
                } catch (Exception e) {
                    throw new DataException("预约失败");
                }
                orederNo = orederNo + "," + carVO.getPlateNumber();
            }
        }

        return orederNo;
    }

    /**
     * 将CarVO转换为QueryReserveSpaceDaHuaDTO
     */
    private QueryReserveSpaceDaHuaDTO carVOtoQueryReserveSpaceDaHuaDTO(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, CarVO carVO){
        QueryReserveSpaceDaHuaDTO queryReserveSpaceDaHuaDTO = new QueryReserveSpaceDaHuaDTO();
        if(carVO != null){
            queryReserveSpaceDaHuaDTO.setCarNum(carVO.getPlateNumber());
            queryReserveSpaceDaHuaDTO.setConsumerName(carVO.getOwnerName());
            queryReserveSpaceDaHuaDTO.setTelNumber(carVO.getOwnerPhone());
            if(StringUtils.isNotEmpty(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemark())){
                queryReserveSpaceDaHuaDTO.setParkingLotCode(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getRemark());
            }else {
                VehicleParkingLot vehicleParkingLot = vehicleParkingLotService.getOne(new LambdaQueryWrapper<VehicleParkingLot>()
                .eq(VehicleParkingLot::getProjectId, vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId()));
                List<VehicleArea> vehicleAreaList = vehicleAreaService.list(new LambdaQueryWrapper<VehicleArea>()
                .eq(VehicleArea::getParkingLotId, vehicleParkingLot.getId()));
                String parkingLotCode="";
                for (VehicleArea vehicleArea : vehicleAreaList) {
                    parkingLotCode=parkingLotCode+vehicleArea.getRemark()+",";
                }
                queryReserveSpaceDaHuaDTO.setParkingLotCode(parkingLotCode);
            }
            queryReserveSpaceDaHuaDTO.setEnterModel(enterModel);
            queryReserveSpaceDaHuaDTO.setExitModel(existModel);
            queryReserveSpaceDaHuaDTO.setReservationType(reservationType);
            queryReserveSpaceDaHuaDTO.setStartTimeStr(AboutDateUtil.dateToString(carVO.getValidBeginTime()));
            queryReserveSpaceDaHuaDTO.setEndTimeStr(AboutDateUtil.dateToString(carVO.getValidEndTime()));
        }
        return queryReserveSpaceDaHuaDTO;
    }

    /**
     * 访客车预约取消
     */
    @Override
    public void cancelReserve(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, String orderNo) {
        //查看是否开启了蒙牛红门双厂商定制化需求
        if(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams() != null){
            JSONObject customParamsObj = JSONObject.parseObject(vehicleIntegratedConfigBO.getVehicleParkingInfoBO().getCustomParams());
            if(customParamsObj.getBoolean("doubleFunContrMn")){
                String[] orderNoArr = orderNo.split(",");
                try {
                    hongMenHttpService.deleteVisitorCar(customParamsObj.getString("host"), orderNoArr[1]);
                } catch (Exception e) {
                    throw new DataException("取消预约失败");
                }
                orderNo = orderNoArr[0];
            }
        }

        List<String> orderNOs = new LinkedList<>();
        orderNOs.add(orderNo);
        try {
            daHuaHttpService.cancelCar(vehicleIntegratedConfigBO, orderNOs);
        }catch (Exception e){
            throw new DataException("取消预约失败");
        }
    }

    /**
     * 将大华道闸通道id转换为道闸id，便于查看通道与设备的绑定关系
     */
    private String passageIdToDeviceId(PassageAndDeviceDaHuaDTO passageAndDeviceDaHuaDTO){
        //判断道闸是否含有一体机
        List<JSONObject> relLeds = passageAndDeviceDaHuaDTO.getRelLeds();
        if(relLeds == null || relLeds.isEmpty()){
            return passageAndDeviceDaHuaDTO.getChannelId();
        }
        for (JSONObject relLed : relLeds) {
            //如果是一体机的话，那么道闸通道id与道闸id的数字前缀相差一，道闸id小一点
            if(relLed.getInteger("deviceCategory") == deviceYiTiJi){
                String deviceIdStr = passageAndDeviceDaHuaDTO.getChannelId().substring(0
                        , passageAndDeviceDaHuaDTO.getChannelId().indexOf(deviceAfterStr));
                Integer deviceIdTrue = Integer.valueOf(deviceIdStr) - 1;
                return deviceIdTrue + deviceAfterStr;
            }
        }
        //如果不是一体机，道闸通道id和道闸id是相同的
        return passageAndDeviceDaHuaDTO.getChannelId();
    }
}
